home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / CMovieController 1.0 / CMovieController Folder / CMovieController.cp < prev    next >
Text File  |  1994-04-26  |  13KB  |  499 lines

  1. /******************************************************************************
  2.  CMovieController.cp
  3.  
  4.         
  5.     SUPERCLASS = CPane
  6.     
  7.     Copyright © 1994 Johns Hopkins University. All rights reserved.
  8.     
  9.     CMovieController is a class which implements the QuickTime Movie Controller
  10.     Component for QuickTime movie playback ONLY.  You should subclass 
  11.     CMovieController to add more functionality by handling other components
  12.     like Sequence Grabber, Clock, and others.
  13.     
  14.     The updating of movies is handled by the MovieController routine MCIdle()
  15.     (which calls MovieTask()) instead of calling MovieTask() directly.  
  16.     This prevents us from having to patch or subclass CSwitchboard in order to 
  17.     handle QT events.
  18.     
  19.     Support for creating CMovieController panes directly from DLOG resources
  20.     by overloading DITL items is also included.  Make sure you copy and use 
  21.     the 'MoCt' TMPL from this projects resource file.
  22.     
  23.     NOTE:  I have added two error strings in STR# 131 for reporting QT errors.
  24.     
  25.     Please let me know if you enhance or expand this class.
  26.     
  27.     Original Author:     Martin R. Wachter        email:    mrw@welchgate.welch.jhu.edu
  28.     
  29.     Modified:            4/20/94                    by:        mrw            TCL Version:    1.1.3
  30.     Created:            4/19/94                    by:        mrw            TCL Version:    1.1.3
  31.  
  32.     Version change history:
  33.     
  34.     1.0        Initial release.
  35.     
  36.  ******************************************************************************/
  37.  
  38. #include "CMovieController.h"
  39. #include <CPaneBorder.h>
  40. #include <TBUtilities.h>
  41.  
  42. extern long            gSleepTime;            /* Max time between events            */
  43.  
  44. /******************************************************************************
  45.  IMovieController
  46.  
  47.         Initialize a Movie object
  48.  ******************************************************************************/
  49.  
  50. void    CMovieController::IMovieController(
  51.     CView            *anEnclosure,
  52.     CBureaucrat        *aSupervisor,
  53.     short            aWidth,
  54.     short            aHeight,
  55.     short            aHEncl,
  56.     short            aVEncl,
  57.     SizingOption    aHSizing,
  58.     SizingOption    aVSizing)
  59. {
  60. OSErr    err = noErr;
  61.  
  62.     TRY{
  63.         // fail if QT is not installed
  64.         err = Gestalt(gestaltQuickTime, 0L);
  65.         if (err != noErr)
  66.             Failure(err,SpecifyMsg(0,5));
  67.         
  68.         // init QT
  69.         FailOSErr(EnterMovies());
  70.     }
  71.     CATCH{
  72.     }
  73.     ENDTRY;
  74.  
  75.     CPane::IPane(anEnclosure, aSupervisor,
  76.                     aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  77.  
  78.     IMovieControllerX();
  79.  
  80. }
  81.  
  82. /******************************************************************************
  83.  IViewTemp
  84.  
  85.      Initialize from a template resource.
  86. ******************************************************************************/
  87.  
  88. void CMovieController::IViewTemp(CView *anEnclosure, CBureaucrat *aSupervisor,
  89.                                 Ptr viewData)
  90. {
  91. OSErr    err = noErr;
  92. FSSpec    spec;
  93. short    numFound;
  94.  
  95.  
  96.     TRY{
  97.         // fail if QT is not installed
  98.         err = Gestalt(gestaltQuickTime, 0L);
  99.         if (err != noErr)
  100.             Failure(err,SpecifyMsg(0,5));
  101.         
  102.         // init QT
  103.         FailOSErr(EnterMovies());
  104.     }
  105.     CATCH{
  106.     }
  107.     ENDTRY;
  108.  
  109.     tMovieControllerTempP MoCtpane = (tMovieControllerTempP) viewData;
  110.     
  111.     CPane::IViewTemp( anEnclosure, aSupervisor, viewData);
  112.  
  113.     IMovieControllerX();
  114.  
  115.     CopyPString(MoCtpane->movieTitle, itsMovieTitle);
  116.  
  117.     //  we will be using the origin of the DITL item
  118.     // and the frame size will be set from the MovieBox
  119.     width = height = 0;
  120.     SetLongRect(&frame, 0,0,0,0);
  121.     CalcAperture();
  122.     
  123.     TRY{
  124.         numFound = LocateMovie(&spec);
  125.  
  126.         if (numFound == 1){
  127.             SetMovie(&spec);
  128.         }
  129.         else if (numFound > 1){
  130.             OpenMovie();
  131.         }
  132.         else{ // movie not found
  133.             Failure(-43,SpecifyMsg(0,6));
  134.         }
  135.     }
  136.     CATCH{
  137.         Dispose();
  138.     }
  139.     ENDTRY;
  140.  
  141.     
  142. }    /* CMovieController::IViewTemp */
  143.  
  144. /******************************************************************************
  145.  IMovieControllerX
  146.  
  147.      Perform common initialization.
  148. ******************************************************************************/
  149.  
  150. void CMovieController::IMovieControllerX(void)
  151. {
  152.     // gimmie a border
  153.     itsBorder = new(CPaneBorder);
  154.     itsBorder->IPaneBorder(kBorderFrame);
  155.  
  156.     // inti data members
  157.     itsMovie = NULL;
  158.     itsMovieRefNum = 0;
  159.     itsController = NULL;
  160.  
  161.     SetWantsClicks(TRUE);
  162.     SetCanBeGopher(TRUE);
  163.     BecomeGopher(TRUE);
  164.     
  165. }    /* CMovieController::IMovieControllerX */
  166.  
  167. /******************************************************************************
  168.  OpenMovie
  169.  
  170.         Initialize a movie from a Macitosh 'Moov' file.
  171.  ******************************************************************************/
  172.  
  173. void    CMovieController::OpenMovie(void)
  174. {
  175. StandardFileReply    sfr;
  176. short                numTypes = 1, rfRefNum;
  177. SFTypeList            sfFileTypes = {MovieFileType};
  178.     
  179.     StandardGetFilePreview(nil, numTypes, sfFileTypes, &sfr);
  180.     
  181.     if (sfr.sfGood){
  182.         SetMovie(&sfr.sfFile);
  183.     }
  184. }
  185.  
  186. /******************************************************************************
  187.  Dispose  {OVERRIDE}
  188.  
  189.         Dispose of a Movie object
  190.  ******************************************************************************/
  191.  
  192. void    CMovieController::Dispose()
  193. {
  194.     ForgetMembers();    
  195.     CPane::Dispose();
  196. }
  197.  
  198. /******************************************************************************
  199.  ForgetMembers
  200.  
  201.         Dispose of a Movie objects
  202.  ******************************************************************************/
  203.  
  204. void    CMovieController::ForgetMembers()
  205. {
  206.     if (itsController)
  207.         DisposeMovieController(itsController);
  208.  
  209.     if (itsMovie)
  210.         DisposeMovie(itsMovie);
  211.  
  212.     if (itsMovieRefNum)
  213.         CloseMovieFile(itsMovieRefNum);
  214.         
  215.     itsMovieRefNum = 0;
  216. }
  217.  
  218. /******************************************************************************
  219.  SetMovie
  220.  
  221.         This routine sets itsMovie and creates and inits our Movie Controller
  222.         from an FSSpec.
  223.  ******************************************************************************/
  224. void    CMovieController::SetMovie(FSSpec *spec)
  225. {
  226. Rect    movieRect,MCRect;
  227. Movie    theMovie;
  228. OSErr    err = noErr;
  229.  
  230.     Prepare();
  231.         
  232.     ForgetMembers();    
  233.     
  234.     FailOSErr(OpenMovieFile(spec, &itsMovieRefNum, fsRdPerm));
  235.     FailOSErr(NewMovieFromFile(&theMovie, itsMovieRefNum, nil, nil, newMovieActive, nil));
  236.     
  237.     itsMovie = theMovie;
  238.     
  239.     GetMovieBox(itsMovie, &movieRect);
  240.     FailOSErr(GetMoviesError());
  241.  
  242.     GoToBeginningOfMovie(itsMovie);            
  243.     FailOSErr(GetMoviesError());
  244.  
  245.     itsController = NewMovieController(itsMovie, &movieRect, mcWithFrame+mcTopLeftMovie);
  246.     FailOSErr(GetMoviesError());
  247.     
  248.     // resize our frame and aperture to the size of the movie and the controller
  249.     MCGetControllerBoundsRect(itsController, &MCRect);
  250.     SetRect(&MCRect, 0, 0, MCRect.right-1, MCRect.bottom-2);
  251.     SetMovieBox(itsMovie, &movieRect);            
  252.     FailOSErr(GetMoviesError());
  253.  
  254.     ResizeFrame(&MCRect);
  255.     CalcAperture();
  256.         
  257.     Refresh();
  258. }
  259.  
  260.  
  261. /******************************************************************************
  262.  NameFileSearch
  263.  
  264.     by Jim Luther, Apple Developer Technical Support
  265.  
  266.     From the File:        MoreFilesExtras.c/ Dev.CD Mar 94    
  267.     Copyright © 1992-1994 Apple Computer, Inc.All rights reserved.
  268.         
  269. ******************************************************************************/
  270.  
  271. OSErr CMovieController::NameFileSearch(StringPtr volName,
  272.                                short vRefNum,
  273.                                const Str255 fileName,
  274.                                FSSpecPtr matches,
  275.                                long reqMatchCount,
  276.                                long *actMatchCount,
  277.                                Boolean newSearch,
  278.                                Boolean partial)
  279. {
  280.     CInfoPBRec        searchInfo1, searchInfo2;
  281.     HParamBlockRec    pb;
  282.     OSErr            error;
  283.     static CatPositionRec catPosition;
  284.     static short    lastVRefNum = 0;
  285.     short            bufferSize = 1024 * 16;
  286.     Str255            fName;
  287.     
  288.     CopyPString(fileName, fName);
  289.  
  290.     pb.csParam.ioNamePtr = nil;
  291.     pb.csParam.ioVRefNum = vRefNum;
  292.     pb.csParam.ioMatchPtr = matches;
  293.     pb.csParam.ioReqMatchCount = reqMatchCount;
  294.     pb.csParam.ioSearchBits = (partial) ?    /* tell CatSearch what we're looking for: */
  295.         (fsSBPartialName + fsSBFlAttrib) :     /* partial name file matches or */
  296.         (fsSBFullName + fsSBFlAttrib);        /* full name file matches */
  297.     pb.csParam.ioSearchInfo1 = &searchInfo1;
  298.     pb.csParam.ioSearchInfo2 = &searchInfo2;
  299.     pb.csParam.ioSearchTime = 0;
  300.     if ((newSearch) ||                /* If caller specified new search */
  301.         (lastVRefNum != vRefNum))    /* or if last search was to another volume, */
  302.         catPosition.initialize = 0;    /* then search from beginning of catalog */
  303.     pb.csParam.ioCatPosition = catPosition;
  304.  
  305.     while(bufferSize) {                
  306.          pb.csParam.ioOptBuffer = NewPtr(bufferSize);
  307.         if(pb.csParam.ioOptBuffer) break;
  308.         else bufferSize -= 1024;
  309.     }
  310.     
  311.     if (pb.csParam.ioOptBuffer) 
  312.         pb.csParam.ioOptBufSize = bufferSize;            
  313.     else 
  314.         pb.csParam.ioOptBufSize = 0;
  315.  
  316.     /* search for fName */
  317.     searchInfo1.hFileInfo.ioNamePtr = (StringPtr)fName;
  318.     searchInfo2.hFileInfo.ioNamePtr = nil;
  319.     
  320.     /* only match files (not directories) */
  321.     searchInfo1.hFileInfo.ioFlAttrib = 0x00;
  322.     searchInfo2.hFileInfo.ioFlAttrib = 0x10;
  323.  
  324.     error = PBCatSearchSync((CSParamPtr)&pb);
  325.  
  326.     if ((error == noErr) ||                            /* If no errors or the end of catalog was */
  327.         (error == eofErr))                            /* found, then the call was successful so */
  328.         *actMatchCount = pb.csParam.ioActMatchCount;    /* return the match count */
  329.     else
  330.         *actMatchCount = 0;                            /* else no matches found */
  331.     
  332.     if ((error == noErr) ||                            /* If no errors */
  333.         (error == catChangedErr))                    /* or there was a change in the catalog */
  334.     {
  335.         catPosition = pb.csParam.ioCatPosition;
  336.         lastVRefNum = vRefNum;
  337.             /* we can probably start the next search where we stopped this time */
  338.     }
  339.     else
  340.         catPosition.initialize = 0;
  341.             /* start the next search from beginning of catalog */
  342.     
  343.     if (pb.csParam.ioOptBuffer)
  344.         DisposPtr(pb.csParam.ioOptBuffer);
  345.         
  346.     return (error);
  347. }
  348.  
  349. /******************************************************************************
  350.  LocateMovie {OVERRIDE}
  351.  
  352.     Tries to locates a Movie from a file name by using NameFileSearch().  If
  353.     the file is found spec returns with a valid FSSpec.
  354.         
  355.  ******************************************************************************/
  356.  
  357. short    CMovieController::LocateMovie(FSSpec *spec)
  358.  
  359. {
  360. OSErr                iErr = noErr;
  361. CInfoPBRec             pb;
  362. long                dirID, totalMatches, maxMatches;
  363. FSSpec                file[2];
  364. short                vRefNum;
  365. Str255                volName;
  366.  
  367.     dirID = 0;                                    // Search Entire Drive;
  368.     vRefNum = -1;                                // Search boot volume;
  369.     maxMatches = 2;                                // Find atleast 2 files
  370.  
  371.  
  372.     pb.hFileInfo.ioNamePtr = volName;
  373.     pb.hFileInfo.ioVRefNum = vRefNum;
  374.     pb.hFileInfo.ioDirID = dirID;
  375.     pb.hFileInfo.ioFDirIndex = -1;    /* get information about ioDirID */
  376.     PBGetCatInfoSync(&pb);
  377.  
  378.     iErr = NameFileSearch(volName, vRefNum, itsMovieTitle, 
  379.                            &file[0], maxMatches, &totalMatches, TRUE, FALSE);
  380.     
  381.     if (totalMatches == 1){
  382.         *spec = file[0];
  383.     }
  384.     
  385.     return totalMatches;
  386.     
  387. }
  388.  
  389. /******************************************************************************
  390.  Activate {OVERRIDE}
  391.  
  392.         Try to handle an Activate event.  If not, pass it up.
  393.         
  394.  ******************************************************************************/
  395.  
  396. void    CMovieController::Activate( void)
  397. {
  398. ComponentResult    result;
  399.     
  400.     Prepare();
  401.     result = MCActivate (itsController, macPort, TRUE);
  402.     if (!result)
  403.         CView::Activate();
  404. }    
  405.  
  406. /******************************************************************************
  407.  Deactivate {OVERRIDE}
  408.  
  409.         Try to handle an Deactivate event.  If not, pass it up.
  410.         
  411.  ******************************************************************************/
  412.  
  413. void    CMovieController::Deactivate( void)
  414. {
  415. ComponentResult    result;
  416.     
  417.     Prepare();
  418.     result = MCActivate (itsController, macPort, FALSE);
  419.     if (!result)
  420.         CView::Deactivate();
  421. }    
  422.  
  423. /******************************************************************************
  424.  DoKeyDown {OVERRIDE}
  425.  
  426.         Respond to a keystroke
  427.  ******************************************************************************/
  428.  
  429. void    CMovieController::DoKeyDown(char theChar,Byte keyCode,EventRecord *macEvent)
  430. {
  431. ComponentResult    result;
  432.  
  433.     Prepare();
  434.     result =  MCKey (itsController, theChar, macEvent->modifiers);    
  435.     if (!result)                        
  436.         itsSupervisor->DoKeyDown(theChar, keyCode, macEvent);
  437. }
  438.     
  439. /******************************************************************************
  440.  DoClick {OVERRIDE}
  441.  
  442.         Respond to a mouse click within the controller.
  443.  ******************************************************************************/
  444.  
  445. void    CMovieController::DoClick(Point hitPt,short modifierKeys,long when)
  446. {
  447. ComponentResult    result;
  448.  
  449.     Prepare();
  450.     result = MCClick(itsController, macPort, hitPt, when, modifierKeys);
  451.     if (!result)
  452.         CView::DoClick(hitPt, modifierKeys, when);
  453. }
  454.  
  455. /******************************************************************************
  456.  Dawdle {OVERRIDE}
  457.  
  458.         Call MoviesTask here if we have a movie and it is playing. MoviesTask()
  459.         handles updating the movie for us. It will update the movie in the background
  460.         also.
  461.         
  462.  ******************************************************************************/
  463.  
  464. void    CMovieController::Dawdle(long    *maxSleep)
  465. {
  466.     Prepare();
  467.     
  468.     if (itsMovie && !IsMovieDone(itsMovie)) {
  469.             gSleepTime = 0;                        // set sleep to minimum
  470.     }
  471.  
  472.     if (itsController)
  473.         MCIdle(itsController);                    // update the movie
  474. }
  475.  
  476. /******************************************************************************
  477.  Draw {OVERRIDE}
  478.  
  479.         Draw a Movie and the controller if need be.
  480.         
  481.  ******************************************************************************/
  482.  
  483. void    CMovieController::Draw(Rect *area)
  484. {
  485.     Rect            tempRect;
  486.     
  487.     Prepare();
  488.     
  489.     // if there is no movie, fill with gray
  490.     if (!itsMovie) {
  491.         LongToQDRect( &aperture, &tempRect);
  492.         FillRect(&tempRect, gray);
  493.     }
  494.     
  495.     // draw the controller
  496.     if (itsController)
  497.         MCDraw(itsController, macPort);
  498. }
  499.